package alchemist.service;

import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import alchemist.dao.CombinationsDao;
import alchemist.dao.ProgressDao;
import alchemist.model.Combination;
import alchemist.model.Element;

@Service
public class DaoCombinationService implements CombinationService
{

    @Autowired
    private CombinationsDao combinationsDao;
    @Autowired
    private ProgressDao progressDao;

    @Override
    public Set< Element > combine( String firstElementId, String secondElementId, String userId )
    {
        Set< Element > results = new HashSet< Element >();
        if ( wereDiscovered( firstElementId, secondElementId, userId ) )
        {
            results = this.combinationsDao.getResults( new Combination( firstElementId, secondElementId ) );
            if ( results != null && !results.isEmpty() )
            {
                this.progressDao.save( userId, results );
            }
        }
        return results;
    }

    @Override
    public Set< Element > getBasicElements()
    {
    	final SortedSet< Element > result = new TreeSet< Element >( this.combinationsDao.getBasicElements() );
        return result;
    }
    
    @Override
    public Set< Element > getDiscovered( String userId )
    {
        final Set< String > elementIds = this.progressDao.retrieveIds( userId );
        final SortedSet< Element > result = new TreeSet< Element >( this.combinationsDao.getElements( elementIds ) );
        result.addAll( this.combinationsDao.getBasicElements() );
        return result;
    }
    
    @Override
    public Integer getTotalCombinations()
    {
    	return this.combinationsDao.getTotalElements();
    }
    
    private boolean wereDiscovered( String firstId, String secondId, String userId )
    {
        final Set< Element > discovered = this.getDiscovered( userId );
        return discovered.contains( this.combinationsDao.retrieveElement( firstId ) ) 
            && discovered.contains( this.combinationsDao.retrieveElement( secondId ) );
    }

}
